package cn.wolfcode.business.service.impl;

import cn.wolfcode.business.domain.BusStatement;
import cn.wolfcode.business.mapper.BusStatementMapper;
import cn.wolfcode.business.service.IBusStatementService;
import cn.wolfcode.business.util.DateUtil;
import cn.wolfcode.business.util.RegexUtils;
import cn.wolfcode.business.util.VehiclePlateNoUtil;
import cn.wolfcode.common.utils.DateUtils;
import cn.wolfcode.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * 结算单Service业务层处理
 * 
 * @author wolfcode
 * @date 2025-04-30
 */
@Service
public class BusStatementServiceImpl implements IBusStatementService 
{
    @Autowired
    private BusStatementMapper busStatementMapper;

    /**
     * 查询结算单
     * 
     * @param id 结算单主键
     * @return 结算单
     */
    @Override
    public BusStatement selectBusStatementById(Long id)
    {
        return busStatementMapper.selectBusStatementById(id);
    }

    /**
     * 查询结算单列表
     * 
     * @param busStatement 结算单
     * @return 结算单
     */
    @Override
    public List<BusStatement> selectBusStatementList(BusStatement busStatement)
    {
        // 获取到额外参数
        String endTime = (String) busStatement.getParams().get("endTime");
        // 将该 String 类型转换为 Date 类型
        Date endTimeDate = DateUtil.parseDate(endTime,"yyyy-MM-dd");
        // 操作 Date 类型 将其 +1 天 -1 秒
        Date date = DateUtil.getEndTime(endTimeDate);
        // 最后再将该 Date 类型转换回 String 类型
        String endDate = DateUtil.parseString(date, "yyyy-MM-dd HH:mm:ss");
        // 将修改后的 endTime 设置到 params.put("endTime",修改后的时间)
        busStatement.getParams().put("endTime",endDate);
        busStatement.setIsDelete(BusStatement.IS_NOT_DELETE);
        return busStatementMapper.selectBusStatementList(busStatement);
    }

    /**
     * 新增结算单
     * 
     * @param busStatement 结算单
     * @return 结果
     */
    @Override
    public int insertBusStatement(BusStatement busStatement)
    {
        //  1. 参数合理化验证。
        if(busStatement == null){
            throw new RuntimeException("非法参数");
        }
        // 	2. 前台所有验证过的后台都要二次验证。（数据不能为 Null）。
        if(busStatement.getCustomerPhone() == null || busStatement.getCustomerName() == null
                || busStatement.getLicensePlate() == null || StringUtils.isEmpty(busStatement.getCarSeries())
                || busStatement.getServiceType() == null || busStatement.getActualArrivalTime() == null){
            throw new RuntimeException("非法参数");
        }
        // 	3. 联系方式合法性验证。
        if(!RegexUtils.isPhoneLegal(busStatement.getCustomerPhone())){
            throw new RuntimeException("手机号码格式有误");
        }
        // 	4. 车牌号码合法性验证。
        VehiclePlateNoUtil.VehiclePlateNoEnum vehiclePlateNo =
                VehiclePlateNoUtil.getVehiclePlateNo(busStatement.getLicensePlate());
        if(vehiclePlateNo == null){
            throw new RuntimeException("车牌号码格式有误");
        }
        // 	5. 到店时间要 < 当前时间。
        Date now = DateUtils.getNowDate();
        if(!busStatement.getActualArrivalTime().before(now)){
            throw new RuntimeException("到店时间有误");
        }
        // 	6. 为了程序安全，我们需要将状态设置为 消费中。
        busStatement.setStatus(BusStatement.STATUS_CONSUME);
        // 安全性：重新设置 is_delete 默认值
        busStatement.setIsDelete(BusStatement.IS_NOT_DELETE);
        busStatement.setCreateTime(DateUtils.getNowDate());
        return busStatementMapper.insertBusStatement(busStatement);
    }

    /**
     * 修改结算单
     * 
     * @param busStatement 结算单
     * @return 结果
     */
    @Override
    public int updateBusStatement(BusStatement busStatement)
    {
        //  1. 参数合理化验证。
        if(busStatement == null){
            throw new RuntimeException("非法参数");
        }
        // 	2. 前台所有验证过的后台都要二次验证。（数据不能为 Null）。
        if(busStatement.getCustomerPhone() == null || busStatement.getCustomerName() == null
                || busStatement.getLicensePlate() == null || StringUtils.isEmpty(busStatement.getCarSeries())
                || busStatement.getServiceType() == null || busStatement.getActualArrivalTime() == null){
            throw new RuntimeException("非法参数");
        }
        // 	3. 联系方式合法性验证。
        if(!RegexUtils.isPhoneLegal(busStatement.getCustomerPhone())){
            throw new RuntimeException("手机号码格式有误");
        }
        // 	4. 车牌号码合法性验证。
        VehiclePlateNoUtil.VehiclePlateNoEnum vehiclePlateNo =
                VehiclePlateNoUtil.getVehiclePlateNo(busStatement.getLicensePlate());
        if(vehiclePlateNo == null){
            throw new RuntimeException("车牌号码格式有误");
        }
        // 	5. 到店时间要 < 当前时间。
        Date now = DateUtils.getNowDate();
        if(!busStatement.getActualArrivalTime().before(now)){
            throw new RuntimeException("到店时间有误");
        }
        // 	6. 状态必须是消费中才可以进行编辑操作
        if(BusStatement.STATUS_PAID.equals(busStatement.getStatus())){
            throw new RuntimeException("必须是消费中才可以进行编辑操作");
        }
        // 修改时是禁止将有效用户修改为无效用户的。所以也要去安全性设置
        if (BusStatement.IS_DELETE.equals(busStatement.getIsDelete())){
            throw new RuntimeException("已被删除的无效用户禁止编辑");
        }
        return busStatementMapper.updateBusStatement(busStatement);
    }

    /**
     * 批量删除结算单
     * 
     * @param ids 需要删除的结算单主键
     * @return 结果
     */
    @Override
    public int deleteBusStatementByIds(Long[] ids)
    {
        return busStatementMapper.deleteBusStatementByIds(ids);
    }

    /**
     * 删除结算单信息
     * 
     * @param id 结算单主键
     * @return 结果
     */
    @Override
    public int deleteBusStatementById(Long id)
    {
        return busStatementMapper.deleteBusStatementById(id);
    }

    /**
     * 结算单软删除
     * @param id
     * @return
     */
    @Override
    public int isDeleteBusStatementById(Long id) {
        //	1. 参数合法性验证。
        if(id == null){
            throw new RuntimeException("非法参数");
        }
        BusStatement statement = this.selectBusStatementById(id);
        if(statement == null){
            throw new RuntimeException("非法参数");
        }
        // 	2. 状态必须是消费中才可以进行删除操作
        if(BusStatement.STATUS_PAID.equals(statement.getStatus())){
            throw new RuntimeException("状态必须为消费中才可以进行删除操作");
        }
        // 3. 实现软删除
        return busStatementMapper.isDeleteBusStatementById(id);
    }

    /**
     * 根据结算单 id 更新结算单总金额，总数量，优惠价。
     * @param statementId
     * @param totalAmount
     * @param totalQuantity
     * @param discountAmount
     * @return
     */
    @Override
    public int updateAmountAndQuantity(Long statementId, BigDecimal totalAmount, BigDecimal totalQuantity, BigDecimal discountAmount) {
        return busStatementMapper.updateAmountAndQuantity(statementId,totalAmount,totalQuantity,discountAmount);
    }

    /**
     * 根据结算单 ID 修改结算单 状态、收款人、收款时间
     * @param statementId
     * @param payId
     * @param date
     * @param statusPaid
     */
    @Override
    public int updateStatusById(Long statementId, Long payId, Date date, Integer statusPaid) {
        return busStatementMapper.updateStatusById(statementId, payId, date, statusPaid);
    }

    /**
     * 根据预约单 ID 查询结算单对象
     * @param id
     * @return
     */
    @Override
    public BusStatement selectByAppointmentId(Long id) {
        return busStatementMapper.selectByAppointmentId(id);
    }

    /**
     * 根据 ID 修改软删除状态
     * @param id
     * @param isDelete
     */
    @Override
    public void changeIsDeleteStatus(Long id, Integer isDelete) {
        busStatementMapper.changeIsDeleteStatus(id,isDelete);
    }
}
